// John Lake
// CSCE 441

#include <stdlib.h>
#include <vector>
#include <list>


// simple structure
struct Point {
	double x, y;
};


struct Color {
	float r, g, b;		// Color (R,G,B values)
};


/**********************************************************************************/


// outline for Edge taken from slides in class
class Edge {
	friend class EdgeList;
	friend class Polygon;

protected:
	int maxY;		// maximum y value of the line
	int minY;		// minimum y value of the line

	double xIncr;	// = 1/slope
					//    will need to deal with case that line is horizontal/vertical

	// may not be needed
	Point p1;	// hold endpoint 1
	Point p2;	// hold endpoint 2
//	Edge* next;	// for use in EdgeList
//	Edge* prev; 


public:
	Edge(Point p1, Point p2);
	~Edge();

	// protect?
	double currentX;	// x-value of endpoint with lowest y value

//	bool compareEdge(Edge first, Edge second);
	bool operator<(Edge& rhs);
	void printEdge();
};


/**********************************************************************************/


class EdgeList {
	friend class Polygon;

protected:

	int elminY;			// which scanline does this list represent?
	int elmaxY;

	//std::list<Edge> edgeList;	// the actual list of edges
	//Edge* edgeList;
	std::list<Edge*> edgeList;

	void addEdge(Edge* _e);	// maybe make into references; am worried about cleaning
							//    of the edge after the function call
	void printEdgeList();



public:
	EdgeList(Edge _e);
	EdgeList(Edge* _e);
	EdgeList();			// remove this later
	~EdgeList();

	bool compareEdgeList(EdgeList first, EdgeList second);
	bool operator<(EdgeList& rhs);

};


/**********************************************************************************/

/*
class ActiveEdgeList : public EdgeList {
public:
	ActiveEdgeList(Edge _e);
	~ActiveEdgeList();

	bool operator<(ActiveEdgeList& rhs);

};
*/


/**********************************************************************************/
	

class Polygon {	// will be one per polygon
private:
	// don't need this?
	int windowWidth, windowHeight;	// window height and width; set in constructor; 
	// determines size of AE Table
	
	
	Color color;	// enumeration?

	// hopefully a vector of pointers to lists of Edges
	//std::vector<std::list<Edge>*>* aeTable;	// table of (nonhorizontal) edges at each scanline
	// ^ original implementation, but will be inefficient (only ~10 vertices, not 800!)
	
	//std::list<std::list<Edge>> aeTable;	

	std::list<EdgeList*> aeTable;	// list of all edges
	std::list<Point*> vTable;	// list of all vertices
	EdgeList aeList;			// list of active edges (for use when drawing)
//	std::list<Edge> aeList;


public:
	Polygon(int _windowWidth, int _windowHeight, Color _color);
	~Polygon();

//	void addEdge(Edge e);	// called when the user left clicks; calls aeTable.addEdge
	void addEdge(Edge* e);

	void drawPolygon();	// will be the one to call setFrameBuffer();
	void printEdgeTable();
	Polygon* clipPolygon(Polygon* original, Point _p1, Point _p2);
};


/**********************************************************************************/

